package com.example.paopao.consumer.memer.alipay.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.example.paopao.consumer.memer.alipay.pojo.dto.PayMent;
import com.example.paopao.consumer.memer.alipay.pojo.param.PayParam;
import com.example.paopao.consumer.memer.alipay.service.PayService;
import com.example.paopao.consumer.memer.dao.cache.IIntegralsCacheRepository;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 处理在线支付相关请求的控制器类
 *
 * @author java@tedu.cn
 * @version 3.0
 */
@Slf4j
@Api(tags = "5. 模拟支付")
@RestController
@RequestMapping("/v1/alipay/")
public class PayController {
/*
    // 应用ID,您的APPID，收款账号既是您的APPID对应支付宝账号
    public static String app_id = "";

    // 商户私钥，您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "";

    // 支付宝公钥,查看地址：https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "";

    // 服务器异步通知页面路径  需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
    public static String notify_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";

    // 页面跳转同步通知页面路径 需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
    public static String return_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";

    // 签名方式
    public static String sign_type = "RSA2";

    // 字符编码格式
    public static String charset = "utf-8";

    // 支付宝网关
    public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";

    // 支付宝网关
    public static String log_path = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";*/




    /**
     * APP ID，请在支付宝沙箱应用（https://open.alipay.com/develop/sandbox/app）中查找正确的值
     */
    private static final String APP_ID = "9021000129655002";
    /**
     * 应用私钥，请在支付宝沙箱应用（https://open.alipay.com/develop/sandbox/app）中查找正确的值
     */
    private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCLn7gauu+SOShKqiRsnrQxRX2LTrC/0LSDTroYJIHUp3lvTVkvnQd1v4UmESiD8kG3LrVHqB9NWJEEPxI4+08nDvjShK3ADu6iBhfrrIcbkoAhvXLLOL/2+9l0zxndbXr5kDlYxFHcgeO7JqRtqtyllOP3NH1kh/FTBthwyvn3i1GmIfEZxaViAY3yF940r4V/jm7e8yubZFva42lZkkKiA/dJj4cc1qnm1c4gEoQjTmJCt+feB0OCmYKBjl6r9scN+BNTHm6ai32ODQH1QqnpiCn5M2MOxKYbGQfEqOe1a26K92FjJeYCriHM/cjgPTmdLtJrSqR+MfQsVgJb4M2dAgMBAAECggEANS9N7cCvaT+kfWx6G3YIpYwW2m3LHgXd/PaMJI4jdmGk/CS2iFCEevHNQkbe7APnzGNaYkVERy4pbzinNFVmPTaSyX4IwVPuyoEPs5IwlOwlKrUDeS3Q0b/1gW0yKQp/AXlSnuGJXTmNCckacTvYeKpSe+Per+CoqDu/TpfCx+wQRPVDPmcyHbcFWMQSgujm1qYfEtoihCpjkiGx8XAz4bij8DP96EXlye68Gjb7aJwJO1SDE2ov715MkSUxuFKi+scY7STkxPMJ2a3n/hFTGatq0gfkqGzTCyC753oUfBJwJhrDKPgqzgDuQNikJ4lLiScmVyV6CuSdUnQ9Mi2ugQKBgQD5UqqF8QW3JGMFRwd4vCqs6cqRKcL6KuYFzlVQm5lqRyMEN2wp6ZU3H+2fgfJfFgPBCvCjzPs+Rv/TBHRUuZ4V9WOixofpOZFqYSP45btZIR3fttohZsLiA3ePFNFOJ+x3qNMnK+y9tn13+SuGWN5gi4DVurunk/KpsMBsTtJV9QKBgQCPXPeZ4iGCeWnVf8Y9xlaPAF0i+p8DOnZMkXwhKO2CpXyuj3O9YyB9KBNlNE5GSBPZtSfh06Dio0YMXI43a9ddphMHC6/5ZyG2LYcwEe9o9BMemZwCCE3xn7v6zBV/e8lpZy1xmB4BTqdpNES73ILfR2MXaRruzPkv6XVZRueoCQKBgQDdmNzZKYzj52JfSW9ZnxzrDOyvMwgKI+DIXkiz2Wh07n8v+zaW1fZ6xVUFRZEvdDin9lpFrCXOh3pPipD+0O+yIqWJAp2/7BvUCjzXtxBaOrX7peCgeV5TVbOJJ36U0aU6AYKTOVY0lCNWY8+MnCYidztuO4cYfcXbjq6oVTJblQKBgCg3G/2+wUeoZ1fMj/+kM4PJxlaZlyGAtM6lwPxMTtPnOCJ/eygVNnflVgt9sLdmYKshdh6TDv6EbpHpJLvHNJLAk3XWgXakx4AjJVkGrvHyBar/zBOF4Nd2x3SC60TnpIg8uTK0STZ0qeGJF/7azJt1mwZmJXf3Z69Y/eIdUb6BAoGBAMgppiJZNHbmgDbJT0JLlRyDAuMWW0b+i5tzGVGY35NHZI0IM+4B+3A8VH+qIOWbiGfBJPjKylXXDOGiMRWMuswa1vFj+YdZONy6xDEyPoG5CHPfz6BxoY/86Xhgsl+Bjd+U0R9IN0JLfRik463HMwRjofs7Z8COFfKdRk3lK2Z2";
    /**
     * 支付宝公钥，请在支付宝沙箱应用（https://open.alipay.com/develop/sandbox/app）中查找正确的值
     */
    private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjFtKKj5WixDJC/G6EQUAswyPDiQB5CoNGzCq0YZTr2W7AxeeGp5v3GEnrqzdKW+XoVVt/yKJjVbtITuoB9jepV1QndI8d28Pz+FvMLwQUCNhwlialFInvZF/1GzAyPxYnnhbXgbNDGH2Un4MLnOz2PlzBit3B+6h86K+T3eDl3i1da6QG0pXj4rHFW1q+hnLLunU47F254y1XKEuKWxW/qeSgTvLEjkGj1ZvTTKJeu7DR2rgf3PYg0OZ0MtQrlzb8BIPoln/iIqkjKB8/CM2XEuU48Ic8pXXOGzjmfJHfQm1Znh1JX6NhkP8fEu/YV3JYR56x3Ns23r1nGojpk3PRwIDAQAB";
    /**
     * 支付服务器的主机，请参考你的服务器配置，或内网穿透的端口映射配置
     */
    private static final String PAY_HOST = "http://localhost:29000";
    /**
     * 通知网址，用于处理支付宝完成支付处理后，你的应用中进行下一步处理的请求地址，请参考当前控制器的配置
     */
    private static final String NOTIFY_URL = PAY_HOST + "/v1/alipay/notify";
    /**
     * 返回网址，用于支付宝完成支付处理后，重定向到某个位置，请参考当前控制器的配置
     */
    private static final String RETURN_URL = PAY_HOST + "/v1/alipay/finish";
    /**
     * 【固定】支付宝网关
     */
    private static final String ALIPAY_GATEWAY = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    /**
     * 【固定】加密算法
     */
    private static final String ENCRYPTION_ALGORITHM = "RSA2";
    /**
     * 【固定】字符编码
     */
    private static final String CHARSET = "UTF-8";
    /**
     * 【固定】数据格式
     */
    private static final String DATA_FORMAT = "json";

    @Autowired
    private IIntegralsCacheRepository integralsCacheRepository;

    @Autowired
    private PayService payService;

    public PayController() {
        log.debug("创建控制器类对象：PayController");
    }

    // 此方法用于接收客户端发起的支付请求，并响应支付表单页面到客户端
    // 网页客户端应该通过window.open直接向此处发起请求，则响应的支付表单会直接显示在window.open打开的窗口中
    @ApiOperation("支付宝沙箱支付")
    @ApiOperationSupport(order = 100)
    @GetMapping("pay")
    public String pay(PayParam payParam, @ApiIgnore HttpServletResponse response) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(
                ALIPAY_GATEWAY, APP_ID, PRIVATE_KEY, DATA_FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, ENCRYPTION_ALGORITHM);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //异步接收地址，仅支持http/https，公网可访问
        request.setNotifyUrl(NOTIFY_URL);
        //同步跳转地址，仅支持http/https
        request.setReturnUrl(RETURN_URL);
        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", payParam.getOutTradeNo());
        //支付金额，最小值0.01元
        bizContent.put("total_amount", payParam.getTotalAmount());
        //订单标题，不可使用特殊符号
        bizContent.put("subject", payParam.getSubject());
        //电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        /******可选参数******/

        ////TODO 商品明细信息，按需传入

        ////TODO 扩展信息，按需传入

        request.setBizContent(bizContent.toString());
        AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(request);
        if (alipayTradePagePayResponse.isSuccess()) {
            String responseBody = alipayTradePagePayResponse.getBody();
            return responseBody;
        } else {
            return "交易失败，调用支付宝远程接口失败，或重新支付！";
        }
    }

    // 接收支付宝发送的通知（支付结果）
    // 注意：必须是POST请求
    @ApiIgnore
    @RequestMapping("notify")
    public String payNotify(@ApiIgnore HttpServletRequest request) throws Throwable {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            params.put(name, request.getParameter(name));
        }
        String sign = params.get("sign");
        String content = AlipaySignature.getSignCheckContentV1(params);
        boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, ALIPAY_PUBLIC_KEY, CHARSET); // 验证签名
        // 支付宝验签
        if (checkSignature) {
            log.debug("支付宝验签:"+checkSignature);//支付宝验签:true
            PayMent payMent=new PayMent();



            // 验签通过
//            log.debug("交易名称: " +);//交易名称: null
            payMent.setSubject( params.get("subject"));
//            log.debug("交易状态: " + params.get("trade_status"));//交易状态: null
            payMent.setTrade_status( params.get("trade_status"));
//            log.debug("支付宝交易凭证号: " + params.get("trade_no"));//支付宝交易凭证号: 2023110422001450340501758969
            payMent.setTrade_no( params.get("trade_no"));
//            log.debug("交易金额: " + params.get("total_amount"));//交易金额: 29.00
            payMent.setTotal_amount( params.get("total_amount"));
//            log.debug("商户订单号: " + params.get("out_trade_no"));//商户订单号: 311699081425700
            payMent.setOut_trade_no( params.get("out_trade_no"));
//            log.debug("买家支付宝ID: " + params.get("buyer_id"));//买家支付宝ID: null
            payMent.setBuyer_id( params.get("buyer_id"));
//            log.debug("买家付款时间: " + params.get("gmt_payment"));//买家付款时间: null
            payMent.setGmt_payment( params.get("gmt_payment"));
//            log.debug("买家付款金额: " + params.get("buyer_pay_amount"));//买家付款金额: null
            payMent.setBuyer_pay_amount( params.get("buyer_pay_amount"));
            // 你应该在此处补充支付成功后续的代码，例如修改订单状态等

            payService.insertPay(payMent);
            // 完成
            return "支付完成";
        } else {
            return "支付失败，或重新支付！";
        }
    }

    // 接收处理支付宝的跳转（支付完成后自动重定向到此处）
    @ApiIgnore
    @GetMapping("finish")
    public String finish(HttpServletRequest request) throws Throwable {
        String notify = payNotify(request);
        if (!notify.equals("支付完成")){
            return notify;
        }
        return notify;
    }

}
